package com.bkitmobile.kesu.android.GUI;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

import com.bkitmobile.kesu.android.ClassInfo.CmtLocation;
import com.bkitmobile.kesu.android.ClassInfo.PlaceAdapter;
import com.bkitmobile.kesu.android.ClassInfo.PlaceInfo;
import com.bkitmobile.kesu.android.ClassInfo.PlaceShortInfo;
import com.bkitmobile.kesu.android.connectServer.Request;
import com.bkitmobile.kesu.android.connectServer.ServiceCallback;
import com.bkitmobile.kesu.android.connectServer.staticClass;
import com.bkitmobile.kesu.android.service.UpdateLocationService;

public class PlaceList extends Activity implements OnClickListener, OnItemClickListener, OnKeyListener{
	
	private Button btnSearch, btnCancel, btnViewCmt, btnLike;
	private ImageButton btnGoDown, btnViewMap;
	private EditText edName;
	private Spinner spType, spDistance;
	private TextView txtName, txtInfo;
	private ListView listResult;
	private LinearLayout layoutSearch, layoutInfo;
	private PlaceAdapter placeAdapter;
	private PlaceShortInfo psInfo;
	private Dialog dlgCmt;
	private double lng, lat;
	
	private Handler handler = new Handler();
	private boolean isSearch;
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search_main);
		btnCancel = (Button) findViewById(R.id.search_main_button_cancel);
		btnLike = (Button) findViewById(R.id.search_main_button_like);
		btnSearch = (Button) findViewById(R.id.search_main_button_search);
		btnViewCmt = (Button) findViewById(R.id.search_main_button_viewCmt);
		btnGoDown = (ImageButton) findViewById(R.id.search_main_button_goDown);
		btnViewMap = (ImageButton) findViewById(R.id.search_main_button_viewMap);
		edName = (EditText) findViewById(R.id.search_main_name);
		spDistance = (Spinner) findViewById(R.id.search_main_distance);
		spType = (Spinner) findViewById(R.id.search_main_type);
		listResult = (ListView) findViewById(R.id.search_main_list);
		layoutSearch = (LinearLayout) findViewById(R.id.search_main_search);
		layoutInfo = (LinearLayout) findViewById(R.id.search_main_info);
		txtName = (TextView) findViewById(R.id.search_main_viewName);
		txtInfo = (TextView) findViewById(R.id.search_main_placeInfo);
		dlgCmt = null;
		psInfo = null;
		spDistance.setAdapter(new ArrayAdapter<String>(this, 
				android.R.layout.simple_dropdown_item_1line, 
				getResources().getStringArray(R.array.search_distance_str)));
		ArrayAdapter<String> typeAdapter = new ArrayAdapter<String>(this, 
				android.R.layout.simple_dropdown_item_1line,
				getResources().getStringArray(R.array.map_items_search));
		spType.setAdapter(typeAdapter);
		listResult.setOnItemClickListener(this);
//		listResult.setOnKeyListener(this);
		btnCancel.setOnClickListener(this);
		btnLike.setOnClickListener(this);
		btnSearch.setOnClickListener(this);
		btnViewCmt.setOnClickListener(this);
		btnGoDown.setOnClickListener(this);
		btnViewMap.setOnClickListener(this);
		Bundle extras = getIntent().getExtras();
		boolean search = extras.getBoolean("search");
		showSearchLayout(search);
		isSearch = extras.getBoolean("search");
		if (!isSearch)
		{
			initList(extras);
			showSearchLayout(false);
		} else {
			lat = extras.getDouble("lat");
			lng = extras.getDouble("lng");
			placeAdapter = new PlaceAdapter(this, new LinkedList<PlaceShortInfo>(), lat, lng);
		}
		listResult.setAdapter(placeAdapter);
	}
	
	/**
	 * get list notification
	 */
	private void initList(Bundle extras)
	{
		lat = UpdateLocationService.currentLocation.getLatitude();
		lng = UpdateLocationService.currentLocation.getLongitude();
		placeAdapter = new PlaceAdapter(this, new LinkedList<PlaceShortInfo>(), lat, lng);
		int size = extras.getInt("size");
		for (int i = 0 ; i < size ; i++)
		{
			PlaceInfo pInfo = (PlaceInfo) extras.getSerializable("place"+i);
			PlaceShortInfo psInfo = new PlaceShortInfo(
					pInfo.getType(), pInfo.getAddress(), 
					pInfo.getName(), pInfo.getLng(), pInfo.getLat());
			placeAdapter.add(psInfo);
		}
		placeAdapter.notifyDataSetChanged();
	}
	@Override
	public void onClick(View v) {
		switch(v.getId()){
			case R.id.search_main_button_cancel:
				if(placeAdapter == null || placeAdapter.getCount()<=0){
					finish();
				}
				layoutSearch.setVisibility(View.INVISIBLE);
				break;
			case R.id.search_main_button_like:
				likePlace();
				break;
			case R.id.search_main_button_search:
				search();
				break;
			case R.id.search_main_button_viewCmt:
				viewComment();
				break;
			case R.id.search_main_button_goDown:
				showInfoLayout(false);
				break;
			case R.id.search_main_button_viewMap:
				focusToMap(psInfo);
				
		}
		
	}

	private void likePlace() {
		PlaceInfo pInfo = psInfo.getPi();
		if (!pInfo.isLike())
		{
			staticClass.socket.println("<like><lat>"+pInfo.getLatE6()+"<lng>"+pInfo.getLngE6());
			pInfo.setLike(true);
			btnLike.setText("Dislike");
		} else {
			staticClass.socket.println("<dislike><lat>"+pInfo.getLatE6()+"<lng>"+pInfo.getLngE6());
			pInfo.setLike(false);
			btnLike.setText("Like");
		}
	}
	private void viewComment() {
		if(dlgCmt == null){
			dlgCmt = new MapCommentsView(this);
		}
		((MapCommentsView)dlgCmt).show(psInfo.getPi());
	}
	public boolean onCreateOptionsMenu(Menu menu) {
		if (isSearch) new MenuInflater(getApplication()).inflate(R.menu.search_menu, menu);
		return (super.onCreateOptionsMenu(menu));
	}
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()){
		case R.id.menu_search_search:
			showSearchLayout(true);
			break;
		}
		
		return(super.onOptionsItemSelected(item));
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
		// TODO Auto-generated method stub
		psInfo = placeAdapter.getItem(position);
		if(psInfo.getPi() == null){
			sendRequestInfo(psInfo);
		}else{
			showInfo();
		}
	}
	private void showSearchLayout(boolean show){
		if(show){
			layoutSearch.setVisibility(View.VISIBLE);
			layoutInfo.setVisibility(View.INVISIBLE);
		}
		else
			layoutSearch.setVisibility(View.INVISIBLE);
	}
	private void showInfoLayout(boolean show){
		if(show){
			layoutSearch.setVisibility(View.INVISIBLE);
			layoutInfo.setVisibility(View.VISIBLE);
		}
		else
			layoutInfo.setVisibility(View.INVISIBLE);
	}
	private void search(){
		showSearchLayout(false);
		String name = edName.getText().toString();
		String type = spType.getSelectedItem().toString();
		int []distaces = getResources().getIntArray(R.array.search_distace_int);
		int distance = distaces[spDistance.getSelectedItemPosition()];
		sendRequestSearch(name, type, distance);
	}
	private void sendRequestSearch(String name, String type, int distance){
		
		//TODO: request search
		String []identities = {"ID","type","name","distance","lat","lng"};
		String []atributies = {Request.SEARCH,type.trim(),name.trim(),String.valueOf(distance)
				,String.valueOf(lat),String.valueOf(lng)};
		Log.d("Stype", type);
		Log.d("Sname", name);
		Log.d("Sdistance", distance+"");
		Log.d("Slat", lat+"");
		Log.d("Slng", lng+"");
		Request.sendAndRecieveData(identities, atributies, true,this,new ServiceCallback<String>() {
			
			@Override
			public void onSuccess(final String result) {
				// TODO Auto-generated method stub]
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						try {
							JSONArray jArr = new JSONArray(result);
							Log.d("Search", "" + jArr.length());
							if(jArr.length() <= 0){
								Toast.makeText(PlaceList.this, R.string.search_error_noresult, Toast.LENGTH_LONG).show();
								showSearchLayout(true);
							}
							else{
								for (int i = 0 ; i < jArr.length() ; i++)
								{
									JSONObject jObject = jArr.getJSONObject(i);
									String resultType = jObject.getString("type");
									String resultName = jObject.getString("name");
									String resultAddress = jObject.getString("addr");
									double resultLat = jObject.getDouble("lat");
									double resultLng = jObject.getDouble("lng");
									//TODO: put type,name,address to list
									placeAdapter.add(new PlaceShortInfo(resultType, resultAddress, resultName, resultLng, resultLat));
								}
								
									placeAdapter.notifyDataSetChanged();
							}
						} catch (JSONException e)
						{
							StaticDialogs.okButtonDialog(PlaceList.this, getString(R.string.place_alert));
						}
					}
				});
			}
			
			@Override
			public void onFailure(Exception exception) {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						StaticDialogs.okButtonDialog(PlaceList.this
								, PlaceList.this.getString(R.string.disconnect));
					}
				});
			}
		});
	}
	private void focusToMap(PlaceShortInfo psi){
		Intent toMapIntent = new Intent(this, MapFocus.class);
		toMapIntent.putExtra("pInfo",psi);
		startActivity(toMapIntent);
	}
	
	private void sendRequestInfo(final PlaceShortInfo shortInfo){
		//TODO: request more info of an place
		String []identities = {"ID","lat","lng"};
		String []atributies = {Request.GET_PLACE_INFO,
				String.valueOf(shortInfo.getLatE6()),
				String.valueOf(shortInfo.getLongE6())};
		Log.d("Send info", "here");
		Request.sendAndRecieveData(identities, atributies, true,this,new ServiceCallback<String>() {
			
			@Override
			public void onSuccess(final String result) {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						try {
							JSONObject obj = new JSONObject(result);
							boolean like = obj.getBoolean("like");
							String creator = obj.getString("userCreate");
							String info = obj.getString("info");
							JSONArray lsCmt = new JSONArray(obj.getString("cmt"));
							List<CmtLocation> listCmt = new ArrayList<CmtLocation>();
							for (int i = 0 ; i < lsCmt.length() ; i++)
							{
								JSONObject newObj = lsCmt.getJSONObject(i);
								String user = newObj.getString("user");
								String cmt = newObj.getString("cmt");
								String time = newObj.getString("time");
								Log.d("obj", newObj.toString());
								CmtLocation newCmt = new CmtLocation(user, cmt,time);
								listCmt.add(newCmt);
							}
							PlaceInfo pi = new PlaceInfo(listCmt, info, creator, shortInfo.getName(), 
									shortInfo.getType(), shortInfo.getAddress(), shortInfo.getLatE6(), 
									shortInfo.getLongE6(), like, false);
							shortInfo.setPi(pi);
							showInfo();
//							PlaceInfo pi = new PlaceInfo(listCmt, info, userCreate, shortInfo.getName(), shortInfo.getType(), 
//									addr, lat, lng, like, true);
						} catch (JSONException e)
						{
							
						}
					}
				});
				
			}
			
			@Override
			public void onFailure(Exception exception) {
				// TODO Auto-generated method stub
				handler.post(new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						StaticDialogs.okButtonDialog(PlaceList.this
								, PlaceList.this.getString(R.string.disconnect));
					}
				});
			}
		});
		
	}
	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_SEARCH){
			layoutSearch.setVisibility(View.VISIBLE);
		}
		
		return false;
	}
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			if (layoutInfo.isShown()) 
			{
				showInfoLayout(false);
				return true;
			}
			else if(layoutSearch.isShown()) {
				showSearchLayout(false);
				if(placeAdapter.getCount() <= 0)
					finish();
				return true;
			}
			else {
				finish();
				return(true);
			}
		}
		else return(super.onKeyDown(keyCode, event));
	}
	private String formatString(String atribute, String content){
		return "<b>" + atribute + ": </b>" + content.replaceAll("\n", "<br/>") + "<br/>";
	}

	private void showInfo() {
		txtName.setText(psInfo.getName());
		String content = formatString(getString(R.string.map_info_creator), psInfo.getPi().getCreator())
		+ formatString(getString(R.string.map_info_type), psInfo.getType())
		+ formatString(getString(R.string.map_info_address), psInfo.getAddress())
		+ formatString(getString(R.string.map_info_distance), psInfo.getDist())
		+ formatString(getString(R.string.map_info_describe), "")
		+ psInfo.getPi().getInfo().replaceAll("\n", "<br/>");
		txtInfo.setText(Html.fromHtml(content));
		showInfoLayout(true);
	}
	
}


